﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;


namespace Glorysoft.EAP.EAPClient.Common
{
    public delegate int HookProc(int nCode, int wParam, IntPtr lParam);

    public static class Win32API
    {
        public const long WS_Caption = 0x00C00000L;
        public const int WM_SYSKEYUP = 0X105;
        public const int WM_SYSKEYDOWN = 0X104;
        public const int MOUSEEVENTF_MOVE = 0x0001;
        public const int MOUSEEVENTF_LEFTDOWN = 0x0002;
        public const int MOUSEEVENTF_LEFTUP = 0x0004;
        public const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
        public const int MOUSEEVENTF_RIGHTUP = 0x0010;
        public const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        public const int MOUSEEVENTF_MIDDLEUP = 0x0040;
        public const int MOUSEEVENTF_ABSOLUTE = 0x8000;

        public const int GWL_STYLE = -16;
        public const int GWL_EXSTYLE = -20;
        public const long WS_EX_APPWINDOW = 0x00040000L;
        public const long WS_EX_TOOLWINDOW = 0x00000080L;

        public const int SW_HIDE = 0;
        public const int SW_SHOWNORMAL = 1;
        public const int SW_SHOWMINIMIZED = 2;
        public const int SW_MAXIMIZE = 3;
        public const int SW_SHOW = 5;

        public delegate bool WNDENUMPROC(IntPtr hWnd, int lParam);
        [DllImport("user32.dll")]
        public static extern int SetCursorPos(int x, int y);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool GetCursorPos(out System.Drawing.Point pt);

        [DllImport("user32.dll")]
        public static extern int GetWindowRect(IntPtr hwnd, out KvmRect lpRect);

        [DllImport("user32.dll")]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);

        [DllImport("user32.dll")]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport("user32")]
        public static extern int mouse_event(int dwFlags, int dx, int dy, int cButtons, IntPtr dwExtraInfo);

        [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
        /// <summary>    
        /// 该函数获得一个指定子窗口的父窗口句柄。
        /// </summary>    
        public static extern IntPtr GetParent(IntPtr hWnd);
        [DllImport("user32.dll")]
        public static extern IntPtr SetParent(IntPtr childPtr, IntPtr parentPtr);
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern bool UpdateWindow(IntPtr hwnd);

        [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        //[DllImport("user32.dll", CharSet = CharSet.Auto)]
        //public static extern int SetWindowLong(IntPtr hWnd, int Index, long Value);

        // This helper static method is required because the 32-bit version of user32.dll does not contain this API
        // (on any versions of Windows), so linking the method will fail at run-time. The bridge dispatches the request
        // to the correct function (GetWindowLong in 32-bit mode and GetWindowLongPtr in 64-bit mode)
        public static IntPtr SetWindowLong(IntPtr hWnd, int nIndex, long Value)
        {
            if (IntPtr.Size == 8)
                return SetWindowLongPtr64(hWnd, nIndex, (IntPtr)Value);
            else
                return new IntPtr(SetWindowLong32(hWnd, nIndex, (int)Value));
        }

        [DllImport("user32.dll", EntryPoint = "SetWindowLong")]
        private static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
        private static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        [DllImport("user32.dll")]
        public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        public static extern IntPtr GetDesktopWindow();
        [DllImport("user32.dll")]
        public static extern IntPtr GetSubMenu(IntPtr hWnd, int nPos);
        [DllImport("user32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern IntPtr GetMenu(IntPtr hWnd);
        [DllImport("user32.dll")]
        public static extern int GetMenuItemID(IntPtr hWnd, int nPos);
        [DllImport("user32.dll")]
        public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
        [DllImport("user32.dll")]
        public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, int lParam);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool MoveWindow(IntPtr hwnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
        [DllImport("user32.dll")]
        public static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll")]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll")]
        public static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)] StringBuilder lpString, int nMaxCount);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern long GetWindowLong(IntPtr hWnd, int Index);

        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
        //=======================================================Mouse Keyborad===================================
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);
        [DllImport("user32.dll")]
        public static extern IntPtr WindowFromPoint(Point Point);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
        public static extern int UnhookWindowsHookEx(int idHook);

       
    }

    public static class GDI32API
    {

        public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
        [DllImport("gdi32.dll")]
        public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
            int nWidth, int nHeight, IntPtr hObjectSource,
            int nXSrc, int nYSrc, int dwRop);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
            int nHeight);
        [DllImport("gdi32.dll")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteDC(IntPtr hDC);
        [DllImport("gdi32.dll")]
        public static extern bool DeleteObject(IntPtr hObject);
        [DllImport("gdi32.dll")]
        public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
    }

    public enum HookTypes
    {
        WH_JOURNALRECORD = 0,
        WH_JOURNALPLAYBACK = 1,
        WH_KEYBOARD = 2,
        WH_GETMESSAGE = 3,
        WH_CALLWNDPROC = 4,
        WH_CBT = 5,
        WH_SYSMSGFILTER = 6,
        WH_MOUSE = 7,
        WH_HARDWARE = 8,
        WH_DEBUG = 9,
        WH_SHELL = 10,
        WH_FOREGROUNDIDLE = 11,
        WH_CALLWNDPROCRET = 12,
        WH_KEYBOARD_LL = 13,
        WH_MOUSE_LL = 14
    }

    public enum MouseEvents
    {
        LeftButtonDown = 0x0201,
        LeftButtonUp = 0x0202,
        Move = 0x0200,
        MouseWheel = 0x020A,
        MButtonDown = 0x0207,
        MButtonUp = 0x0208,
        RightButtonDown = 0x0204,
        RightButtonUp = 0x0205
    }

    [StructLayout(LayoutKind.Sequential)]
    public class MouseLLHookStruct
    {
        public Point pt;
        public int mouseData;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct KeyMSG
    {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    public enum MouseEventType
    {
        None,
        MouseDown,
        MouseUp,
        DoubleClick,
        MouseWheel,
        MouseMove
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct WindowInfo
    {
        public IntPtr hWnd;
        public IntPtr ChildHandle;
        public string EqpID;
        public string EqpName;
        public string EqpClassName;
    }
    public struct KvmRect
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }


    public static class UpdateWinStyle
    {
        //-------------------------------------------------------
        public static IntPtr FindPCHandle(string caption)
        {
            IntPtr mwh = IntPtr.Zero;
            mwh = Win32API.FindWindow(null, caption);
            if (mwh != IntPtr.Zero && mwh != null)
            {
                return mwh;
            }
            return IntPtr.Zero;
        }

        public static void WindowClose(IntPtr hWnd)
        {
            Win32API.SendMessage(hWnd, 0x112, 0xF060, 0);
            //PostMessage(hWnd, 0x0010, 0, 0);
        }
        public static void SetUpCaption(IntPtr hWnd)
        {

            long WindowStyle = Win32API.GetWindowLong(hWnd, -16);
            int Caption = (int)(WindowStyle & ~Win32API.WS_Caption & ~Win32API.WS_EX_APPWINDOW & ~Win32API.WS_EX_TOOLWINDOW);
            //int Caption = (int)(WindowStyle | Win32API.WS_Caption);
            Win32API.SetWindowLong(hWnd, -16, Caption);
        }
        public static void GetUpCaption(IntPtr hWnd)
        {
            long WindowStyle = Win32API.GetWindowLong(hWnd, -16);
            int Caption = (int)(WindowStyle & ~Win32API.WS_Caption & ~Win32API.WS_EX_APPWINDOW & ~Win32API.WS_EX_TOOLWINDOW);
            //int Caption = (int)(WindowStyle & ~Win32API.WS_Caption);
            Win32API.SetWindowLong(hWnd, -16, Caption);
        }
        #region 预览控制界面加载
        /// <summary>
        /// 去掉最大最小化
        /// </summary>
        public static void SetFormStyle(IntPtr handle, int x, int Width, int Height)
        {
            GetUpCaption(handle);
            Win32API.SetWindowPos(handle, 0, x, 0, Width, Height, 0x01);
            Win32API.ShowWindow(handle, 1);
            Win32API.EnableWindow(handle, false);
        }
        /// <summary>
        /// KVM控制窗体操作
        /// </summary>
        public static void moveLoad(IntPtr handle, int Width, int Height)
        {
            Win32API.EnableWindow(handle, true);
            Win32API.SetWindowPos(handle, 0, 0, 0, Width, Height, 0x02);
        }
        /// <summary>
        /// KVM控制窗体操作
        /// </summary>
        public static void KvmFormLoad(IntPtr handle, IntPtr Hwnd, int Width, int Height)
        {
            Win32API.EnableWindow(handle, true);
            Win32API.SetParent(handle, Hwnd);
            Win32API.SetWindowPos(handle, 0, 0, 0, 0, 0, 0x01 | 0x08);
        }
        #endregion

        #region 控制窗体关闭事件
        /// <summary>
        /// 控制窗体关闭事件
        /// </summary>
        public static void MonitorControlClose(IntPtr handle, IntPtr HWnd, int x)
        {
            Win32API.SetParent(handle, HWnd);
            Win32API.SetWindowPos(handle, 0, x, 0, 0, 0, 0x01 | 0x08);
            Win32API.ShowWindow(handle, 1);
            Win32API.EnableWindow(handle, false);
        }
        #endregion
    }
}
